package com.lark;

import atlantafx.base.theme.Styles;
import com.alibaba.fastjson2.JSONArray;
import com.lark.constant.AppConstant;
import com.lark.constant.FileConstant;
import com.lark.context.ApplicationContext;
import com.lark.exception.CustomException;
import com.lark.model.TaskModel;
import com.lark.utils.FileUtil;
import com.lark.utils.ImageUtil;
import com.lark.utils.NodeUtil;
import com.lark.utils.StageUtil;
import javafx.application.Platform;
import javafx.concurrent.ScheduledService;
import javafx.concurrent.Task;
import javafx.geometry.Pos;
import javafx.scene.Node;
import javafx.scene.Scene;
import javafx.scene.layout.HBox;
import javafx.scene.layout.StackPane;
import javafx.scene.paint.Color;
import javafx.scene.text.Font;
import javafx.scene.text.FontPosture;
import javafx.scene.text.FontWeight;
import javafx.scene.text.Text;
import javafx.stage.Stage;
import javafx.util.Duration;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;

import java.io.File;
import java.io.IOException;
import java.nio.channels.FileChannel;
import java.nio.channels.FileLock;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.nio.file.StandardOpenOption;
import java.time.LocalDate;
import java.time.ZoneId;
import java.time.temporal.ChronoUnit;
import java.util.List;
import java.util.Random;

import static com.lark.context.ApplicationContext.clientModel;
import static com.lark.context.ApplicationContext.root;


@Slf4j
public class TestApplication extends JavaFxApplication {

    @Override
    public StackPane showInitialView(Stage primaryStage, double width, double height) {
        primaryStage.getIcons().add(ImageUtil.getIcon("tray.png"));
        primaryStage.setTitle("任务倒计时");
        root = new StackPane();
        Scene scene = new Scene(root, width, height);
        primaryStage.setScene(scene);
        primaryStage.show();
        primaryStage.setResizable(false);
        return root;
    }

    @Override
    public void initLoading() {

    }

    @Override
    public void afterLoading() {
        try {
            Path filePath = Paths.get(FileConstant.DEFAULT_CONF_PATH, clientModel.defaultConfPath(), "task.json");
            if (!Files.exists(filePath)) {
                Files.createFile(filePath);
            }
            String json = FileUtil.parse(filePath.toString());
            if (StringUtils.isNotBlank(json)) {
                List<TaskModel> taskModels = JSONArray.parseArray(json, TaskModel.class);
                ApplicationContext.taskModelList.addAll(taskModels);

                for (TaskModel taskModel : ApplicationContext.taskModelList) {
                    LocalDate now = LocalDate.now(ZoneId.systemDefault());
                    long days = ChronoUnit.DAYS.between(now, taskModel.date());
                    if (days <= 0) {
                        log.warn("目标日期必须大于当前日期，任务:{}", taskModel.name());
                        continue;
                    }

                    // 展示的内容
                    Text first = new Text("距离" + taskModel.name() + "还有");
                    first.setFont(Font.font(taskModel.fontSize()));
                    first.setFill(Color.valueOf(taskModel.fontColor()));
                    first.getStyleClass().add(Styles.TEXT);

                    Text second = new Text(days + "");
                    second.setFont(Font.font("Arial", FontWeight.BOLD, FontPosture.ITALIC, taskModel.fontSize() + 10));
                    second.setFill(Color.RED);
                    second.getStyleClass().add(Styles.TEXT);

                    Text third = new Text("天");
                    third.setFont(Font.font(taskModel.fontSize()));
                    third.setFill(Color.valueOf(taskModel.fontColor()));
                    third.getStyleClass().add(Styles.TEXT);

                    HBox hBox = new HBox(first, second, third);
                    hBox.setAlignment(Pos.CENTER_LEFT);
                    hBox.setUserData(taskModel.date());

                    ApplicationContext.taskModelMap.put(taskModel.name(), hBox);
                }

                // 随机展示一个
                if (!ApplicationContext.taskModelMap.isEmpty()) {
                    Platform.runLater(() -> {
                        Stage showStage = StageUtil.show((Node) ApplicationContext.taskModelMap.values().toArray()[0]);
                        NodeUtil.drag(ApplicationContext.SHOW_STACK_PANE, showStage);
                    });
                }
            }

            // 启动定时器
            ScheduledService<Integer> service = new ScheduledService<>() {
                @Override
                protected Task<Integer> createTask() {
                    return new Task<>() {
                        @Override
                        protected Integer call() throws Exception {
                            if (ApplicationContext.taskModelMap.isEmpty()) {
                                throw new CustomException();
                            }
                            // 随机展示一个
                            Random random = new Random();
                            return random.nextInt(ApplicationContext.taskModelMap.size() - 1);
                        }

                        @Override
                        protected void succeeded() {
                            HBox hbox = (HBox) ApplicationContext.taskModelMap.values().toArray()[getValue()];
                            Text text = (Text) hbox.getChildren().get(1);
                            LocalDate now = LocalDate.now(ZoneId.systemDefault());
                            long days = ChronoUnit.DAYS.between(now, (LocalDate) hbox.getUserData());
                            text.setText(days + "");
                            ApplicationContext.SHOW_STACK_PANE.getChildren().clear();
                            ApplicationContext.SHOW_STACK_PANE.getChildren().add(hbox);
                            log.info("切换成功");
                        }
                    };
                }
            };
            // 什么时候启动
            service.setDelay(Duration.seconds(30d));
            // 间隔时间
            service.setPeriod(Duration.seconds(30d));
            service.start();
        } catch (Exception e) {
            log.error("任务解析出错", e);
        }
    }

    public static void main(String[] args) {
        File file = new File(FileConstant.DEFAULT_CONF_PATH, ".alarmClock/alarmClock.lock");
        File fileParent = file.getParentFile();
        if (fileParent != null && !fileParent.exists()) {
            //创建文件夹
            fileParent.mkdirs();
        }
        try (FileChannel fc = FileChannel.open(file.toPath(), StandardOpenOption.CREATE, StandardOpenOption.WRITE);
             FileLock lock = fc.tryLock()) {
            if (lock == null) {
                log.warn("another instance is running");
                System.exit(AppConstant.ALREADY_RUNNING_EXIT_CODE);
            }
            launch(args);
        } catch (IOException e) {
            log.error("File channel operation encountered an exception: ", e);
            System.exit(AppConstant.ALREADY_RUNNING_EXIT_CODE);
        }
    }
}
